package net.airtheva.uniqueTask4.view;

import net.airtheva.uniqueTask4.LyricParser;
import net.airtheva.uniqueTask4.Utils;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

public class LyricScrollView extends ScrollView {

	public static final String TAG = "LyricScrollView";
	
	public static final int CURRENT_INDEX_UNKNOWN = -1;
	
	public static final int SIZE_PADDING = 8;
	public static final int SIZE_TEXT_DEFAULT = 16;
	public static final int SIZE_TEXT_HIGHLIGHT = 24;
	
	public interface OnTimeChangedListener {
		
		void OnTimeChanged(int newTime);
		
	}
	
	LinearLayout mContainer;
	
	Paint mCenterLine;
	
	Long[] mTimes;
	
	boolean mIsLoaded = false;
	boolean mIsSeeking = false;
	
	TextView mCurrentTextView;
	
	OnTimeChangedListener mOnTimeChangedListener;
	
	public LyricScrollView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		
		setup();
		
	}
	
	public LyricScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		
		setup();
	}

	
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		// TODO Auto-generated method stub
		super.onSizeChanged(w, h, oldw, oldh);
		// Ensure the current line is in the middle.
		mContainer.setPadding(0, h / 2, 0, h / 2);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		
		int centerY = getCenterY();
		
		canvas.drawLine(0, centerY, getWidth(), centerY, mCenterLine);
	}

	@Override
	public void fling(int velocityY) {
		// TODO Auto-generated method stub
		//super.fling(velocityY);
	}

	protected void setup() {
		
		setVerticalScrollBarEnabled(false);
		ViewCompat.setOverScrollMode(this, ViewCompat.OVER_SCROLL_NEVER);
		
		mContainer = new LinearLayout(getContext());
		mContainer.setOrientation(LinearLayout.VERTICAL);
		
		mCenterLine = new Paint();
		mCenterLine.setColor(0xffffffff);
		
		addView(mContainer);
		
	}
	
	protected void onTimeChanged(int newTime) {
		
		mOnTimeChangedListener.OnTimeChanged(newTime);
		
	}
	
	protected int getCenterY() {
		
		int centerY = getScrollY() + getHeight() / 2;
		return centerY;
		
	}
	
	protected TextView findTextViewByPosition(float x, float y) {
		
		int size = mContainer.getChildCount();
		for(int i = 0; i < size; i++) {
			
			TextView textView = (TextView) mContainer.getChildAt(i);
			
			if(textView.getTop() < y && textView.getBottom() > y) {
				return textView;
			}
			
		}
		
		return null;
		
	}
	
	// Use to change the current line, and automatically scroll to it.
	protected void setCurrentIndex(int currentIndex) {
		
		if(mIsLoaded) {
			
			if(currentIndex == CURRENT_INDEX_UNKNOWN) {
				return;
			}
			
			int count = mContainer.getChildCount();
			for(int i = 0; i < count; i++) {
				TextView textView = (TextView) mContainer.getChildAt(i);
				if(i != currentIndex) {
					textView.setTextSize(SIZE_TEXT_DEFAULT);
				}
				else {
					textView.setTextSize(SIZE_TEXT_HIGHLIGHT);
					mCurrentTextView = textView;
				}
			}
			
			smoothScrollTo(0, mCurrentTextView.getTop() + mCurrentTextView.getMeasuredHeight() / 2 - getMeasuredHeight() / 2);
			//scrollTo(0, mCurrentTextView.getTop() + mCurrentTextView.getMeasuredHeight() / 2 - getMeasuredHeight() / 2);
			
		}
		
	}
	
	// Fill text into the LyricScrollView.
	public void SetLyricParser(LyricParser lyricParser) {
		
		mTimes = lyricParser.GetTimes();
		
		String[] lines = lyricParser.GetLines();
		
		mContainer.removeAllViews();
		
		for(int i = 0; i < lines.length; i++) {
			
			String line = lines[i];
			
			TextView textView = new TextView(getContext());
			textView.setTag(i);
			
			textView.setPadding(SIZE_PADDING, SIZE_PADDING, SIZE_PADDING, SIZE_PADDING);
			textView.setGravity(Gravity.CENTER);
			textView.setText(line);
			
			mContainer.addView(textView);
			
		}
		
		mContainer.requestLayout();
		
		mIsLoaded = true;
		
	}
	
	public void SetOnTimeChangedListener(OnTimeChangedListener l) {
		
		mOnTimeChangedListener = l;
		
	}
	
	public void SetTime(long time) {
		
		if(mIsLoaded && !mIsSeeking) {
			
			int index = Utils.FindArea(mTimes, time);
			
			if(index >= 0) {
				setCurrentIndex(index);
			}
			else {
				Log.d(TAG, "FindArea == -1.");
			}
			
		}
		
	}
	
	public void StartSeeking() {
		
		mIsSeeking = true;
		
	}
	
	public void UpdateSeeking() {
		
		if(mIsLoaded && mIsSeeking) {
			
			TextView currentTextView = findTextViewByPosition(getWidth() / 2, getCenterY());
			// FIXME: Debugging.
			if(currentTextView != null) {
				Log.d(TAG, currentTextView.getTag() + "");
				
				// CurrentIndex is changing.
				if(currentTextView != mCurrentTextView) {
					
					int newIndex;
					int oldIndex;
					
					newIndex = (Integer) currentTextView.getTag();
					
					if(mCurrentTextView != null) {
						oldIndex = (Integer) mCurrentTextView.getTag();
					}
					else {
						oldIndex = CURRENT_INDEX_UNKNOWN;
					}
					
					setCurrentIndex(newIndex);
					
					if(mOnTimeChangedListener != null) {
						mOnTimeChangedListener.OnTimeChanged((int) (long) mTimes[newIndex]);
					}
						
				}
				
			}
		}
		
	}
	
	public void EndSeeking() {
		
		mIsSeeking = false;
		
	}
	
}
